{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# -*- coding: utf-8 -*-\n",
    "# @Time    : 18-10-16 下午12:20\n",
    "# @Author  : Felix Wang\n",
    "\n",
    "import pyaudio\n",
    "import numpy as np\n",
    "from scipy import fftpack\n",
    "import wave\n",
    "from playsound import playsound\n",
    "import time\n",
    "\n",
    "###############  MAC录音功能说明  ################\n",
    "# recording方法包含3个参数，\n",
    "#     filename : 录音后，声音存储到的文件名\n",
    "#     time     : 录音的时间，0为不限定时间，根据声音是否结束来停止\n",
    "#                          不为0的值，录制x秒\n",
    "#     threshold: 麦克风停止录音的门限值，默认为7000\n",
    "# init初始化方法：\n",
    "#        需要传入百度AI应用提供的APP_ID、API_KEY和SECRET_KEY\n",
    "# speech_2_word语音识别方法： \n",
    "#        识别的音频文件名，格式为.mp3\n",
    "#################################################\n",
    "\n",
    "#########  调用方式举例  #################\n",
    "#导入标准库\n",
    "# import sys\n",
    "# import os\n",
    "# from playsound import playsound\n",
    "\n",
    "# #导入自定义库\n",
    "# sys.path.append('../../baidu_api_lib')\n",
    "# import voice_record\n",
    "\n",
    "# if __name__ == \"__main__\":\n",
    "#     try:\n",
    "#         #进行麦克风录音\n",
    "#         voice_record.recording(\"voice_test.mp3\", 0, 8000)\n",
    "        \n",
    "#         #播放录制的声音\n",
    "#         playsound(\"voice_test.mp3\")\n",
    "    \n",
    "#         #删除临时文件\n",
    "#         os.remove(\"voice_test.mp3\")\n",
    "        \n",
    "#     except KeyboardInterrupt:\n",
    "#         print(\"任务被终止了\")\n",
    "#################################################\n",
    "\n",
    "# 录音\n",
    "# 录音必须安装portaudio模块，否则会报错\n",
    "# http://portaudio.com/docs/v19-doxydocs/compile_linux.html\n",
    "def recording(filename, time=0, threshold=7000):\n",
    "    \"\"\"\n",
    "    :param filename: 文件名\n",
    "    :param time: 录音时间,如果指定时间，按时间来录音，默认为自动识别是否结束录音\n",
    "    :param threshold: 判断录音结束的阈值\n",
    "    :return:\n",
    "    \"\"\"\n",
    "    CHUNK = 512  # 块大小\n",
    "    FORMAT = pyaudio.paInt16  # 每次采集的位数\n",
    "    CHANNELS = 1  # 声道数\n",
    "    RATE = 44100  # 采样率：每秒采集数据的次数\n",
    "    RECORD_SECONDS = time  # 录音时间\n",
    "    WAVE_OUTPUT_FILENAME = filename  # 文件存放位置\n",
    "    p = pyaudio.PyAudio()\n",
    "    stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK)\n",
    "    print(\"* 录音中...\")\n",
    "    frames = []\n",
    "    if time > 0:\n",
    "        for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):\n",
    "            data = stream.read(CHUNK)\n",
    "            frames.append(data)\n",
    "    else:\n",
    "        stopflag = 0\n",
    "        stopflag2 = 0\n",
    "        while True:\n",
    "            data = stream.read(CHUNK)\n",
    "            rt_data = np.frombuffer(data, np.dtype('<i2'))\n",
    "            # print(rt_data*10)\n",
    "            # 傅里叶变换\n",
    "            fft_temp_data = fftpack.fft(rt_data, rt_data.size, overwrite_x=True)\n",
    "            fft_data = np.abs(fft_temp_data)[0:fft_temp_data.size // 2 + 1]\n",
    "\n",
    "            # 测试阈值，输出值用来判断阈值\n",
    "            # print(sum(fft_data) // len(fft_data))\n",
    "\n",
    "            # 判断麦克风是否停止，判断说话是否结束，# 麦克风阈值，默认7000\n",
    "            if sum(fft_data) // len(fft_data) > threshold:\n",
    "                stopflag += 1\n",
    "            else:\n",
    "                stopflag2 += 1\n",
    "            oneSecond = int(RATE / CHUNK)\n",
    "            if stopflag2 + stopflag > oneSecond:\n",
    "                if stopflag2 > oneSecond // 3 * 2:\n",
    "                    break\n",
    "                else:\n",
    "                    stopflag2 = 0\n",
    "                    stopflag = 0\n",
    "            frames.append(data)\n",
    "    print(\"* 录音结束\")\n",
    "    stream.stop_stream()\n",
    "    stream.close()\n",
    "    p.terminate()\n",
    "    with wave.open(WAVE_OUTPUT_FILENAME, 'wb') as wf:\n",
    "        wf.setnchannels(CHANNELS)\n",
    "        wf.setsampwidth(p.get_sample_size(FORMAT))\n",
    "        wf.setframerate(RATE)\n",
    "        wf.writeframes(b''.join(frames))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
